package core

//SearchData 我们声明了一个名为done的通道，其中包含struct{}类型的数据。我们使用一个空结构体作为类型，因为它的值并不重要。
//并且我们不会向这个通道写入数据，只是关闭它。
//随后我们为每个传入的searcher启动一个goroutine。
//启动的goroutine中的select语句要么等待在result通道上的写操作（当searcher函数返回时），
//要么等待读取done通道上的数据。记住，在打开的通道上读取数据会阻塞，直到有可用的数据，
//而在关闭的通道上读取数据总是返回该通道的零值。这意味着从done读取的情况将保持阻塞，直到done被关闭。
//在searchData中，我们读取写入result的第一个值，然后关闭done通道。
//关闭通道后，goroutine收到信号，然后退出，防止它们泄露
func SearchData(s string, searchers []Searcher) []string {
	done := make(chan struct{})
	result := make(chan []string)

	for _, searcher := range searchers {
		go func(searcher Searcher) {
			select {
			case result <- searcher.Search(s):
			case <-done:
			}
		}(searcher)
	}

	r := <-result
	close(done)
	return r
}
